#pragma once
class BinStream{
public:
	virtual void  Write(void* data,DWORD size)=0;
	virtual DWORD   Read(void* data,DWORD size)=0;
	virtual void  WriteToFile(const char* Name)=0;
	virtual void  ReadFromFile(const char* Name)=0;
	virtual DWORD   Size()=0;
	virtual void  SetReadPos(DWORD pos)=0;
	virtual void  SetWritePos(DWORD pos)=0;
	virtual DWORD   GetReadPos()=0;
	virtual DWORD   GetWritePos()=0;
	virtual BYTE* GetData()=0;
	virtual void  Clear()=0;
			void  WriteBYTE(BYTE c);
			void  WriteWORD(WORD w);
			void  WriteDWORD(DWORD D);
			BYTE  ReadBYTE();  
			WORD  ReadWORD();
			DWORD ReadDWORD();
};
class FILE_WriteBinStream:public BinStream{
	ResFile F;    
	DWORD Pos;

	BYTE* TempBuffer;
	DWORD TempSize;
	DWORD TempCurrSize;
	DWORD TempPos;
public:
	FILE_WriteBinStream(const char* Name=NULL);
	~FILE_WriteBinStream();	
	bool Valid();
	virtual void  Write(void* data,DWORD size);
	virtual DWORD   Read(void* data,DWORD size);
	virtual void  WriteToFile(const char* Name);
	virtual void  ReadFromFile(const char* Name);
	virtual DWORD   Size();
	virtual void  SetReadPos(DWORD pos);
	virtual void  SetWritePos(DWORD pos);
	virtual DWORD   GetReadPos();
	virtual DWORD   GetWritePos();
	virtual BYTE* GetData();
	virtual void  Clear();
};

class FILE_ReadBinStream:public BinStream{
	ResFile F;
	DWORD Pos;
	DWORD fSize;

	BYTE* TempBuffer;
	DWORD TempSize;
	DWORD TempPos;
	DWORD TempCurrSize;
public:
	FILE_ReadBinStream(const char* Name=NULL);
	~FILE_ReadBinStream();	
	bool Valid();
	virtual void  Write(void* data,DWORD size);
	virtual DWORD Read(void* data,DWORD size);
	virtual DWORD Skip(DWORD size);
	virtual void  WriteToFile(const char* Name);
	virtual void  ReadFromFile(const char* Name);
	virtual DWORD Size();
	virtual void  SetReadPos(DWORD pos);
	virtual void  SetWritePos(DWORD pos);
	virtual DWORD   GetReadPos();
	virtual DWORD   GetWritePos();
	virtual BYTE* GetData();
	virtual void  Clear();
};

class cData {
public:
	cData(){
		Reader=NULL;
		Writer=NULL;
	}
	~cData();
	void Clear();
	
	const cStr & GetFilePn() const { return m_FilePn; }
	void SetFilePn(const char *FilePn, bool ForWrite);
	
	bool IsEof();
	size_t Size();
	int GetPos();
	
	// Moves the data position pointer to a new location that is "Offset" bytes from origin.
	// Returns the offset, in bytes, of the new position from the beginning of the data.
	int SeekCur(const int Offset);	
	int SetPos(const int Pos);
	
	// Returns the number of bytes actually read, which may be less than MaxSize if the end of data
	// is encountered before reaching MaxSize.
	int Read(void *To, const int MaxSize);
	void Write(const void *Fm, const int Size);	
	
	byte ReadByte();
	bool ReadByte(byte *b) ;
	void WriteByte(const byte b);
	
	short ReadShort();
	bool ReadShort(short *s) ;
	void WriteShort(const short s);

	word ReadWord();
	bool ReadWord(word *w);
	void WriteWord(const word w);

	int  ReadInt();
	bool ReadInt(int *i);
	void WriteInt(const int i);

	dword ReadDword();
	bool ReadDword(dword *dw);
	void WriteDword(const dword dw);

	float ReadFloat();
	bool ReadFloat(float *f);
	void WriteFloat(float f);

	double ReadDouble();
	bool ReadDouble(double *d);
	void WriteDouble(double d);
	
	bool ReadString(cStr *, const char *Terminators = "\r\n");
	void WriteString(const char *);
private:
	cStr m_FilePn;
	FILE_ReadBinStream* Reader;	
	FILE_WriteBinStream* Writer;	
};
//*****************************************************************************
// cMeshCodec
//*****************************************************************************
class cMeshCodec {
public:
	cMeshCodec() {}
	virtual ~cMeshCodec() {}
	virtual cMeshConatainer * Decode(cData &Fm) = 0;
	virtual void Encode(const cMeshConatainer &Mesh, cData *To) = 0;
	virtual bool CanEncode(){return true;}
	virtual bool CanDecode(){return true;}
};